package com.heima.comment.service.iml;

import com.heima.aliyun.GreenTextScan;
import com.heima.comment.service.CommentHotService;
import com.heima.comment.service.CommentService;
import com.heima.common.exception.CustException;
import com.heima.feigins.ApUserFeigin;
import com.heima.model.comment.dtos.CommentDTO;
import com.heima.model.comment.dtos.CommentLikeDTO;

import com.heima.model.comment.dtos.CommentSaveDTO;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.vos.ApCommentVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.record.DVALRecord;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CommentServiceImpl implements CommentService {


    @Autowired
    GreenTextScan greenTextScan;

    @Autowired
    ApUserFeigin apUserFeigin;

    @Autowired
    MongoTemplate mongoTemplate;


    /*@Value("${file.oss.web-site}")
    String webSite;*/
    /*
    * 保存评论
    * */
    @Override
    public ResponseResult saveCommentLike(CommentSaveDTO dto) {

        //1. 校验参数
        //1.1校验是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null){
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN,"用户未登录");
        }
        //1.2校验文章id   校验内容不为空  校验内容长度不能大于140个字符 (validated校验)
       // 2. 阿里云校验评论内容是否违规
        boolean flag=true;
        try {
            Map map = greenTextScan.greenTextScan(dto.getContent());
            String suggestion = (String) map.get("suggestion");
            switch (suggestion) {
                case "block":
                    log.info("阿里云文本审核不通过");
                    flag=false;
                    break;
                case "review":
                    log.info("阿里云文本审核不确定，有擦边球行为");
                    flag=false;
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
                log.info("阿里云文本审核出现异常，异常原因    "+e.getMessage());
            flag=false;
        }
        if (!flag){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW,"阿里云检测有问题，内容检测未通过");
        }
       // 3. 远程查询当前登陆用户信息
        ResponseResult<ApUser> apUserById = apUserFeigin.findApUserById(user.getId());
        if (!apUserById.checkCode()){
            CustException.cust(AppHttpCodeEnum.REMOTE_SERVER_ERROR,"ApUserFeigin远程调用出现错误");
        }
        ApUser data = apUserById.getData();
        if (data == null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"App用户信息不存在");
        }
        //4. 创建评论信息，并保存到mongo
        Query query = Query.query(Criteria.where("id").is(dto.getArticleId()).and("authorId").is(user.getId()));
        ApComment one = mongoTemplate.findOne(query, ApComment.class);
        if (one !=null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"评论信息已存在，您已评论过");
        }
        ApComment apComment = new ApComment();
        apComment.setAuthorId(user.getId());
        apComment.setAuthorName(user.getName());
        apComment.setArticleId(dto.getArticleId());
        apComment.setImage(user.getImage());
        apComment.setType((short) 0);
        apComment.setContent(dto.getContent());
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        apComment.setFlag((short) 0);
        apComment.setLikes(0);
        apComment.setReply(0);
        mongoTemplate.save(apComment);
        HashMap<String, Object> map = new HashMap<>();
        map.put("likes",apComment.getLikes());
        ResponseResult result = ResponseResult.okResult(map);
        //result.setHost(webSite);
        return result;
    }

    /*
    * 点赞评论
    * */
    @Autowired
    CommentHotService commentHotService;
    @Override
    public ResponseResult like(CommentLikeDTO dto) {
        //1. 参数校验
        //1.1评论id不能为空  operation必须为 0  或  1,注解实现
        //1.1校验是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null){
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN,"用户未登录");
        }
        //2. 根据评论id查询评论数据， 为返回错误信息
        Query query = Query.query(Criteria.where("id").is(dto.getCommentId()));
        ApComment one = mongoTemplate.findOne(query, ApComment.class);
        if (one ==null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"评论信息不存在");
        }
        //3. 如果是点赞操作 判断是否已经点赞
        //找到用户id,判断点过赞没
        Query loginUser = Query.query(Criteria.where("authorId").is(user.getId()).and("commentId").is(dto.getCommentId()));
        ApCommentLike one1 = mongoTemplate.findOne(loginUser, ApCommentLike.class);
        if (dto.getOperation().intValue()==0 ){
           if (one1==null) {
               // 未点过赞   保存点赞信息到mongo
               ApCommentLike apCommentLike = new ApCommentLike();
               apCommentLike.setAuthorId(user.getId());
               apCommentLike.setCommentId(dto.getCommentId());
               apCommentLike.setOperation((short) 0);
               mongoTemplate.save(apCommentLike);
               // 并修改评论信息的点赞数量( + 1)
               one.setLikes(one.getLikes()+1);
               one.setUpdatedTime(new Date());
               mongoTemplate.save(one);
               //计算点赞评论
               if (one.getLikes()>=10 && one.getFlag().intValue()==0){
                   commentHotService.hotCommentExecutor(one);
               }
           }else {//点过赞提示 请勿重复点赞
               CustException.cust(AppHttpCodeEnum.DATA_EXIST,"请勿重复点赞");
           }
        }else {
            //  4. 如果是取消点赞操作
            //删除点赞信息
            mongoTemplate.remove(one1);
            // 并修改评论信息的点赞数量( - 1) , 要判断下别减成负数
            if (one.getLikes()>0) {
                one.setLikes(one.getLikes() - 1);
            }
            one.setUpdatedTime(new Date());
            mongoTemplate.save(one);
        }
        //5. 返回结果时，需要返回点赞点赞数量  返回的key要求必须是:  likes
        HashMap<String, Object> map = new HashMap<>();
        map.put("likes",one.getLikes());
        ResponseResult result = ResponseResult.okResult(map);
        //result.setHost(webSite);
        return result;
    }

    /*
    * 加载评论列表,根据文章id
    * */
    @Override
    public ResponseResult loadCommentByArticleId(CommentDTO dto) {

        //1. 参数校验
        // 校验文章id,注解校验
       // 校验size
        if (dto.getSize()==0 || dto.getSize()==null){
            dto.setSize(10);
        }
        if (dto.getMinDate()==null){
            dto.setMinDate(new Date());
        }
        //判断是文章首页吗
        List<ApComment> apComments=new ArrayList<>();
        if (dto.getIndex().intValue()==1){
            //2. 根据条件查询评论列表
            Query query = Query.query(Criteria.where("articleId").is(dto.getArticleId())
                    .and("flag").is(1))
                    .with(Sort.by(Sort.Direction.DESC, "likes"));
             apComments = mongoTemplate.find(query, ApComment.class);
             //普通评论第一页显示的条数
            if (!CollectionUtils.isEmpty(apComments)){
                Integer size= dto.getSize();
              size=size-apComments.size();
                Query query1 = Query.query(Criteria.where("articleId").is(dto.getArticleId())
                        .and("createdTime").lt(dto.getMinDate()).and("flag").is(0)).limit(size)
                        .with(Sort.by(Sort.Direction.DESC, "createdTime"));
                List<ApComment> apComments1 = mongoTemplate.find(query1, ApComment.class);
                apComments.addAll(apComments1);
            }else {
                Query query2 = Query.query(Criteria.where("articleId").is(dto.getArticleId())
                        .and("createdTime").lt(dto.getMinDate()).and("flag").is(0)).limit(dto.getSize())
                        .with(Sort.by(Sort.Direction.DESC, "createdTime"));
                apComments = mongoTemplate.find(query2, ApComment.class);
            }
        }else {//不是文章首页
            Query query3 = Query.query(Criteria.where("articleId").is(dto.getArticleId())
                    .and("createdTime").lt(dto.getMinDate()).and("flag").is(0)).limit(dto.getSize())
                    .with(Sort.by(Sort.Direction.DESC, "createdTime"));
            apComments = mongoTemplate.find(query3, ApComment.class);
        }

       // 3. 判断当前用户是否登录
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null){
           // 4. 如果未登录直接返回评论列表
           return ResponseResult.okResult(apComments);
        }
        //5. 如果登录了 需要检查在当前评论列表中 哪些评论登陆人点赞过
            //遍历集合，根据评论id查询出改评论都被谁点赞过，
        //获取文章评论的所有id  ,使用流
        List<String> commentIds = apComments.stream().map(map -> map.getId()).collect(Collectors.toList());
        Query query1 = Query.query(Criteria.where("commentId").in(commentIds).and("authorId").is(user.getId()));
         //查询登录用户点赞的记录
        List<ApCommentLike> apCommentLikes1 = mongoTemplate.find(query1, ApCommentLike.class);
        //5.2 遍历评论列表, 将每一个评论  ApComment 转成 ApCommentVO
        List<ApCommentVo> apCommentVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(apComments) && !CollectionUtils.isEmpty(apCommentLikes1)) {
            for (ApComment apComment : apComments) {
                ApCommentVo apCommentVo = new ApCommentVo();
                BeanUtils.copyProperties(apComment,apCommentVo);
                //遍历当前点赞表
                for (ApCommentLike apCommentLike : apCommentLikes1) {
                    if (apComment.getId().equals(apCommentLike.getCommentId())){
                        apCommentVo.setOperation((short) 0);
                        break;
                    }
                }
                apCommentVos.add(apCommentVo);
            }
            return ResponseResult.okResult(apCommentVos);
        }
        return ResponseResult.okResult(apComments);
    }
}
